#include "communication-device-sniffing.h"
#include <arpa/inet.h>

CommunicationDeviceSniffing::CommunicationDeviceSniffing(SmartDeviceManager *manager)
    : smartDeviceManager(manager)
{
    handle["query"] = &CommunicationDeviceSniffing::query;
}

void CommunicationDeviceSniffing::communication(SmartDeviceNetProtocol &netProtocol, NetCommunication *netObj)
{
    string command = netProtocol.getCommand();
    auto func = handle[command];
    if (!func)
    {
        return;
    }
    (this->*func)(netProtocol, netObj);
}

void CommunicationDeviceSniffing::query(SmartDeviceNetProtocol &netProtocol, NetCommunication *netObj)
{
    string command = netProtocol.getCommand();
    uint32_t deviceType = netProtocol.getDeviceType();
    uint32_t deviceNumber = netProtocol.getDeviceNumber();

    vector<uint8_t> deviceInfo;
    // 设备地址(4byte) + 设备类型(2byte) + 设备编号(1byte)
    bool ok = smartDeviceManager->sniffingDevice(deviceType, deviceNumber, deviceInfo);

    string errmsg = ok ? "" : "error";
    // string data   = ok ? to_string(sensorData) : "0x00";
    string data = "";
    if (ok)
    {
        // deviceInfo [00 00 00 00 01 / 00 01 / 00]
        // 转成小端模式 ntohl 大端转小端模式
        uint32_t deviceAddress = ntohl(*(uint32_t *)&deviceInfo[0]);
        uint16_t deviceType = ntohs(*(uint16_t *)&deviceInfo[4]);
        // 单个字节不考虑字节序
        uint8_t deviceNumber = *(uint8_t *)&deviceInfo[6];
        char buf[100];
        sprintf(buf, "0x%08x&0x%04x&0x%02x", deviceAddress, deviceType, deviceNumber);
        data = buf;
    }
    replay(netObj, command, errmsg, data);
    return;
}

void CommunicationDeviceSniffing::replay(NetCommunication *netObj,
                                         const string &command,
                                         const string &errmsg,
                                         const string &data)
{
    SmartDeviceNetProtocol netProtocol;
    netProtocol.addOperation("sensor");
    netProtocol.addCommand(command);
    netProtocol.addResult(errmsg, data);
    string repalyJsonData = netProtocol.toString();

    vector<uint8_t> packet;
    packet.assign(repalyJsonData.begin(), repalyJsonData.end());
    cout << "------------udp发送----------------" << repalyJsonData << endl;
    bool ret = netObj->sendPacket(packet);
    if (ret != true)
    {
        fprintf(stderr, "Fail to sendPacket\n");
        return;
    }

    return;
}
